import React, { createContext, useContext, useEffect, useReducer, ReactNode, useMemo } from 'react';
import { ConfigProvider, theme } from 'antd';
import dayjs from 'dayjs';

import 'dayjs/locale/zh-cn';
import 'dayjs/locale/zh-tw';
import 'dayjs/locale/en';

// 先不支持以下多语
// import 'dayjs/locale/bn-bd';
// import 'dayjs/locale/fa';
// import 'dayjs/locale/id';
// import 'dayjs/locale/ja';
// import 'dayjs/locale/pt-br';

import _ from 'lodash-es';
import { RawIntlProvider, getLocale, getIntl, localeInfo } from '../locale';

import { setCssVar } from '@/utils';

type Theme = 'light' | 'dark';
type MenuMode = 'vertical' | 'horizontal' | 'inline';
type TokenId =
    | 'default'
    | 'blue'
    | 'purple'
    | 'pink'
    | 'orange'
    | 'green'
    | 'yellow'
    | 'gray_dark'
    | 'gray'
    | 'gray_light';

type Locale = 'zh-US' | 'zh-CN' | 'zh-TW';
interface State {
    tokenId: TokenId;
    theme: Theme;
    locale: Locale;
    rootFontSize: number;
    layout: {
        menuMode: MenuMode;
        showFooter: false;
        showHeader: true;
        showSlider: true;
    };
    intl: any;
}
interface IRootConfigContext extends State {
    setTokenId: (tokenId: TokenId) => void;
    setTheme: (theme: Theme) => void;
    setLocale: (locale: Locale) => void;
    setRootFontSize: (rootFontSize: number) => void;
    setLayout: (layout: any) => void;
}

export const RootConfigContext = createContext<IRootConfigContext>({
    tokenId: 'default',
    theme: 'light',
    locale: 'zh-CN',
    rootFontSize: 12,
    layout: {
        menuMode: 'vertical',
        showFooter: false,
        showHeader: true,
        showSlider: true,
    },
    intl: null,
    setTokenId(tokenId: TokenId) {},
    setTheme(theme: Theme) {},
    setLocale(locale: Locale) {},
    setRootFontSize(rootFontSize: number) {},
    setLayout(layout: any) {},
});

interface Action {
    type: string;
    [key: string]: any;
}

const { darkAlgorithm, compactAlgorithm } = theme;
function reducer(state: State, action: Action) {
    switch (action.type) {
        case 'setTokenId': {
            return {
                ...state,
                tokenId: action.tokenId,
            };
        }
        case 'setTheme': {
            return {
                ...state,
                theme: action.theme,
            };
        }
        case 'setLocale': {
            return {
                ...state,
                locale: action.locale,
            };
        }
        case 'setIntl': {
            return {
                ...state,
                intl: action.intl,
            };
        }
        case 'setRootFontSize': {
            return {
                ...state,
                rootFontSize: action.rootFontSize,
            };
        }
        case 'setLayout': {
            return {
                ...state,
                layout: {
                    ...state.layout,
                    ...action.layout,
                },
            };
        }
        default: {
            throw Error('Unknown action: ' + action.type);
        }
    }
}

function getThemeConfig(theme: Theme, tokenId: TokenId) {
    // 浅色主题
    const lightTheme = {
        theme: {
            token: {},
            components: {
                Layout: {
                    bodyBg: 'rgba(255, 255, 255, 0.65)',
                    headerBg: '#e8edf4',
                    lightSiderBg: '#e8edf4',
                    lightTriggerBg: '#e8edf4',
                    lightTriggerColor: '#1677ff',
                    headerHeight: 60,
                },
            },
            cssVar: true,
        },
        customCssVar: {},
    };

    // 黑色主题
    const darkTheme = {
        theme: {
            token: {
                // colorBgContainer: '#001529',
                colorBgElevated: '#001529',
                colorText: '#fff',
                colorIcon: '#fff',
            },
            components: {
                Layout: {
                    headerBg: '#001529',
                    headerHeight: 60,
                    headerColor: 'rgba(255, 255, 255, 0.65)',
                    bodyBg: '#051139',
                    footerBg: '#001529',
                },
                Tabs: {
                    cardBg: 'red',
                    itemSelectedColor: 'rgba(255, 255, 255, 0.65)',
                },
                Button: {
                    primaryShadow: '0 2px 0 rgba(5, 145, 255, 0.1)',
                },
                Input: {
                    hoverBg: '#fff',
                    activeBg: '#fff',
                },
            },
            cssVar: true,
        },
        customCssVar: {},
    };

    // 预置 主题token
    const customThemeMap = {
        default: {
            theme: {
                token: {
                    colorPrimary: '#1677ff',
                },
                components: {
                    Layout: {},
                },
            },
            customCssVar: {},
        },
        blue: {
            theme: { token: { colorPrimary: '#1fb6ff' } },
            customCssVar: {},
        },
        purple: {
            theme: { token: { colorPrimary: '#7e5bef' } },
            customCssVar: {},
        },
        pink: {
            theme: { token: { colorPrimary: '#ff49db' } },
            customCssVar: {},
        },
        orange: {
            theme: { token: { colorPrimary: '#ff7849' } },
            customCssVar: {},
        },
        green: {
            theme: { token: { colorPrimary: '#13ce66' } },
            customCssVar: {},
        },
        yellow: {
            theme: { token: { colorPrimary: '#ffc82c' } },
            customCssVar: {},
        },
        gray_dark: {
            theme: { token: { colorPrimary: '#273444' } },
            customCssVar: {},
        },
        gray: {
            theme: { token: { colorPrimary: '#8492a6' } },
            customCssVar: {},
        },
        gray_light: {
            theme: { token: { colorPrimary: '#d3dce6' } },
            customCssVar: {},
        },
    };

    return theme === 'dark'
        ? _.merge(darkTheme, customThemeMap[tokenId] || {})
        : _.merge(lightTheme, customThemeMap[tokenId] || {});
}

/**
 * 上下文Provider
 * @param {*} param0
 * @returns
 */
export function RootConfigProvider({ children }: { children: ReactNode }) {
    const initLocale = getLocale() as Locale; // 获取初始化locale

    /**
     * 使用useReducer
     */
    const [state, dispatch] = useReducer(reducer, {
        tokenId: (localStorage.getItem('_tokenId') as TokenId) || 'default',
        theme: (localStorage.getItem('_theme') as Theme) || 'light',
        locale: initLocale, // en
        rootFontSize: 12,
        layout: {
            menuMode: 'vertical', // 菜单 mode vertical 垂直 | horizontal 水平 inline 内嵌
            showFooter: false,
            showHeader: true,
            showSlider: true,
        },
        intl: getIntl(initLocale),
    });

    const themeConfig = getThemeConfig(state.theme, state.tokenId);

    useEffect(() => {
        localStorage.setItem('_locale', state.locale);
        if (dayjs?.locale) {
            dayjs.locale(localeInfo[state.locale]?.momentLocale || '');
        }
    }, [state.locale]);

    useEffect(() => {
        if (state.theme === 'dark') {
            document.documentElement.classList.add('dark');
        } else {
            document.documentElement.classList.remove('dark');
        }
    }, [state.theme]);

    useEffect(() => {
        const customCssVar = themeConfig?.customCssVar || {};
        Object.entries(customCssVar).forEach(([key, value]) => {
            setCssVar(key, value as string);
        });
    }, [themeConfig]);

    function setTokenId(tokenId: TokenId = 'default') {
        localStorage.setItem('_tokenId', tokenId);
        dispatch({
            type: 'setTokenId',
            tokenId,
        });
    }

    function setTheme(theme: Theme = 'light') {
        localStorage.setItem('_theme', theme);
        dispatch({
            type: 'setTheme',
            theme,
        });
    }

    // 设置local
    function setLocale(locale = 'zh-CN') {
        dispatch({
            type: 'setLocale',
            locale,
        });
        dispatch({
            type: 'setIntl',
            intl: getIntl(locale),
        });
    }

    function setRootFontSize(rootFontSize = 12) {
        dispatch({
            type: 'setRootFontSize',
            rootFontSize,
        });
    }

    function setLayout(layout = {}) {
        dispatch({
            type: 'setLayout',
            layout,
        });
    }

    //
    const value = useMemo(
        () => ({
            ...state,
            setTokenId,
            setTheme,
            setLocale,
            setRootFontSize,
            setLayout,
        }),
        [state],
    );

    return (
        <RootConfigContext.Provider value={value}>
            <ConfigProvider
                theme={themeConfig.theme}
                locale={localeInfo[state.locale]?.antd}
                // algorithm={[darkAlgorithm, compactAlgorithm]}
            >
                <RawIntlProvider value={state.intl}>{children}</RawIntlProvider>
            </ConfigProvider>
        </RootConfigContext.Provider>
    );
}

/**
 * 获取上下文
 * @returns
 */
export function useRootConfig() {
    return useContext(RootConfigContext);
}
